package com.asialjim.wechat.spring.filter;

import com.asialjim.wechat.message.DefaultWeChatCallMessage;
import com.asialjim.wechat.pojo.account.WeChatAccountHolder;
import com.asialjim.wechat.utils.JsonUtils;
import com.asialjim.wechat.utils.XmlUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Objects;

/**
 * <h1><em>ASIAL JIM JAVA DOC</em></h1><hr/>
 * <h2>CLASS DESCRIPTION <i>[ NAME: WeChatRequestWrapper ]</i></h2><strong>
 * <p> we chat request wrapper
 * </strong><p><p><em>Copyright &copy; Asial Jim Co., LTD</em><hr/>
 *
 * @author Asial Jim &nbsp;&nbsp; <span>Email:<a href="mailto:asialjim@hotmail.com">asialjim@hotmail.com</a> &nbsp;&nbsp; <a href="asialjim@qq.com">asialjim@qq.com</a></span>
 * @version 1.0.0
 * @since 2021/3/16   &nbsp;&nbsp; JDK 8
 */
public class WeChatRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;

    public WeChatRequestWrapper(HttpServletRequest request) {
        super(request);
        String bodyString = WeChatHttpHelper.bodyString(request);
        body = bodyString.getBytes(Charset.forName("UTF-8".intern()));

        String toUserName = null;

        String contentType = request.getContentType();
        if (Objects.isNull(contentType)) {return;}
        if (contentType.startsWith(ContentType.MULTIPART_FORM_DATA.getMimeType())){
            toUserName = request.getParameter("ToUserName");
            if (StringUtils.isNotBlank(toUserName)){
                WeChatAccountHolder.setToUserName(toUserName);
            }
        }

        if (contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType())){
            Map<String, Object> bodyMap = JsonUtils.jsonToMap(bodyString);
            if (Objects.nonNull(bodyMap) && bodyMap.containsKey("ToUserName")){
                toUserName = (String) bodyMap.get("ToUserName");
                if (StringUtils.isNotBlank(toUserName)) {
                    WeChatAccountHolder.setToUserName(toUserName);
                }
            }
        }

        if (contentType.startsWith(ContentType.APPLICATION_XML.getMimeType()) || contentType.startsWith(ContentType.TEXT_XML.getMimeType())){
            DefaultWeChatCallMessage callMessage = XmlUtils.xml2Object(bodyString, DefaultWeChatCallMessage.class);
            if (Objects.nonNull(callMessage) && StringUtils.isNotBlank(callMessage.getToUserName())){
                WeChatAccountHolder.setToUserName(callMessage.getToUserName());
            }
        }

        toUserName = request.getParameter("ToUserName");
        if (StringUtils.isBlank(WeChatAccountHolder.getToUserName()) && StringUtils.isNotBlank(toUserName)){
            WeChatAccountHolder.setToUserName(toUserName);
        }
    }

    @Override
    public BufferedReader getReader() throws IOException{
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream(){
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
        return new ServletInputStream(){
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
                // empty method
            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }
}
